home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 4 / The 640 Meg Shareware Studio CD-ROM Volume IV (Data Express)(1994).ISO / wp / ehp10.zip / MAIN.C < prev    next >
C/C++ Source or Header  |  1993-06-19  |  37KB  |  999 lines

  1. /****************************************************************/
  2. /*                                                              */
  3. /*      MODUL:  main.c                                          */
  4. /*                                                              */
  5. /*      FUNKTIONEN:                                             */
  6. /*              - pe_or (Fehlertext ausgeben ohne refresh)      */
  7. /*              - print_err (Fehlertext ausgeben)               */
  8. /*              - wart_ret (warte auf RETURN)                   */
  9. /*              - no_mem_err (Fehlermeldung, wenn kein Speicher)*/
  10. /*              - reserve_mem (Speicher reservieren)            */
  11. /*              - save_text (Textzeile sichern)                 */
  12. /*              - line_free (Zeile freigeben)                   */
  13. /*              - revcpy (String von hinten kopieren)           */
  14. /*              - fwdcpy (String von vorne kopieren)            */
  15. /*              - swap_int (zwei integer vertauschen)           */
  16. /*              - ja_nein (Lese JA/NEIN Abfrage)                */
  17. /*              - catchsig (Signal abfangen)                    */
  18. /*              - init (initialisieren)                         */
  19. /*              - ende (Editor beenden)                         */
  20. /*              - save_all (alle geaenderten Texte abspeichern) */
  21. /*              - alles_frei (alle Speicherbereiche freigeben)  */
  22. /*              - do_wildcard_expansion (Wildcards expandieren) */
  23. /*              - hndl_params (Parameter verarbeiten)           */
  24. /*              - main (Hauptprogramm)                          */
  25. /*                                                              */
  26. /****************************************************************/
  27.  
  28. #define aktdef  /* Damit in defs.h nicht lokales als extern deklariert wird */
  29.  
  30. #ifdef OS2
  31. #include <os2.h>
  32. #else
  33. #pragma inline
  34. #include <dir.h>
  35. #endif
  36. #include "defs.h"
  37. #include <signal.h>
  38.  
  39. extern char *getenv(),*sd_line,helpflag;
  40. #undef getch()
  41. extern int read_config();
  42. #ifdef MOUSE
  43. extern int mouse_jn; /* Variable für Maus in ja_nein */
  44. extern char mouse_active;
  45. #ifdef OS2
  46. extern short int mouse_handle;
  47. extern TID mouse_ThreadID, mouse_jn_ThreadID;
  48. #endif /* OS2 */
  49. #endif /* MOUSE */
  50.  
  51. void wart_ret(), ende(int, char);
  52.  
  53. /* *** globale Daten und Initialisierung *** */
  54. win_typ    *akt_winp;            /* Aktuelles Fenster                     */
  55. WINDOW     *status;              /* Statusfenster                         */
  56. short int  aktcode;              /* Aktueller Befehlstastencode           */
  57. short int  *keystack,            /* Zeiger auf aktuelles Pufferzeichen    */
  58.        *e_keystack,          /* Zeiger auf Pufferende                 */
  59.        mc_index;             /* Anzahl der Tastenkombinationen-1      */
  60. int        ks_index = -1;        /* Index des aktuellen Puffers           */
  61. int        blockattr,            /* Attribut zum Highlighten eines Blocks */
  62.        ersetzaddr,           /* Attribut fuer zu ersetzenden String   */
  63.        def_tab = STD_TAB;    /* Laenge eines Tabulatorsprungs         */
  64. char       highblockflag = TRUE, /* Sollen Bloecke gehighlighted werden ? */
  65.        backupflag=TRUE,      /* Es sollen .bak-Files erzeugt werden   */
  66.        def_aiflag = FALSE;   /* Normalerweise kein Autoindent         */
  67. char       *conffile = PF_CONFIG,/* Pfad der Config-Datei                 */
  68.        *loadfile = PF_LOAD;  /* Pfad des Loadfiles                    */
  69. block_typ  global_block;         /* Paste-Puffer fuer globalen Block      */
  70. marker_typ marker[ANZ_MARKER];   /* Feld fuer alle Marker                 */
  71. puff_typ   macro[ANZ_MACROS];    /* Feld fuer alle Macros                 */
  72. char       clear_buff = FALSE,   /* soll Puffer bei naechsten newwgetch() */
  73.                  /* geloescht werden? */
  74.        *tasten_inf = PF_TASTEN; /* Name des Tastenbelegungsfiles      */
  75. #ifdef OS2
  76. HMTX       sem_handle;           /* Handle für Semaphor, der Zusammelspiel*/
  77. #else                            /* von Tastatur uns Maus synchronisiert  */
  78. long       old_int;              /* Zwischenspeicher Vektor des Break-Ints*/
  79. #endif
  80.  
  81. /*****************************************************************************
  82. *
  83. *  Funktion       Fehlertext ausgeben ohne setz_cursor() (pe_or)
  84. *  --------
  85. *
  86. *  Parameter    : fehlertext:
  87. *                   Typ          : char*
  88. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  89. *                   Bedeutung    : Auszugebender Fehlertext
  90. *
  91. *  Beschreibung : Der Fehlertext wird mit print_stat() ausgegeben, anschlie-
  92. *                 ssend wird ein wart_ret ausgefuehrt, dann wird das Status-
  93. *                 fenster geloescht.
  94. *
  95. *****************************************************************************/
  96.  
  97. void pe_or(fehlertext)
  98. char *fehlertext;
  99. {
  100.   print_stat(fehlertext);  /* Text im Statusfenster anzeigen */
  101.   wart_ret();              /* Auf RETURN warten              */
  102.   clear_stat();            /* Statuszeile wieder loeschen    */
  103. }
  104.  
  105. /*****************************************************************************
  106. *
  107. *  Funktion       Fehlertext ausgeben (print_err)
  108. *  --------
  109. *
  110. *  Parameter    : fehlertext:
  111. *                   Typ          : char*
  112. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  113. *                   Bedeutung    : Auszugebender Fehlertext
  114. *
  115. *  Beschreibung : Der Fehlertext wird mit pe_or ausgegeben, anschliessend
  116. *                 wird der Cursor wieder positioniert.
  117. *
  118. *****************************************************************************/
  119.  
  120. void print_err(fehlertext)
  121. char *fehlertext;
  122. {
  123.   pe_or(fehlertext);    /* Fehlermeldung ausgeben und aus RETURN warten */
  124.   if(akt_winp->winp)    /* nur wenn schon ein window angefordert wurde  */
  125.     setz_cursor(W_AKT);      /* s. koppel_win() */
  126. }
  127.  
  128. /*****************************************************************************
  129. *
  130. *  Funktion       warte auf RETURN (wart_ret)
  131. *  --------
  132. *
  133. *  Beschreibung : Der Text " Bitte RETURN druecken..." wird in der
  134. *                 Statuszeile ausgegeben, anschliessend wird auf RETURN
  135. *                 gewartet.
  136. *
  137. *****************************************************************************/
  138.  
  139. void wart_ret()
  140. {
  141.   /* *** interne Daten *** */
  142.   char dummy; /* "String", der mit read_stat eingelesen wird */
  143.  
  144.   print_stat (PROMPT_ENTER);
  145.   read_stat(&dummy,0,GS_ANY); /* String der Laenge 0 einlesen */
  146.   clear_stat();               /* Statuszeile wieder loeschen  */
  147. }
  148.  
  149. /*****************************************************************************
  150. *
  151. *  Funktion       "Kein Speicher" - Fehlermeldung (no_mem_err)
  152. *  --------
  153. *
  154. *  Beschreibung : Eine Fehlermeldung wird ausgegeben und nach einer Rueck-
  155. *                 frage die Dateien gespeichert und das Programm beendet.
  156. *
  157. *****************************************************************************/
  158.  
  159. void no_mem_err()
  160. {
  161.   win_typ *w = akt_winp->next->next; /* Zum Freigeben der Fenster */
  162.  
  163.   while(w!=akt_winp)  /* Alle WINDOW-Strukturen aller Fenster freigeben */
  164.   {                   /* um Speicherplatz zu gewinnen */
  165.     delwin(w->winp); /* Damit Fenster nicht nochmals von delwin freigegeben */
  166.     w->winp = NULL;  /* wird, Pointer auf NULL setzen */
  167.     w = w->next;     /* Zum nächsten Fenster */
  168.   }
  169.   clear_stat();
  170.   print_stat(PROMPT_OUTOFMEM);
  171.   if(ja_nein(PROMPT_SAVE)) /* Abfrage */
  172.     save_all();                  /* Alle geaenderten Dateien sichern */
  173.   ende(1, TRUE);  /* Editor beenden, Rueckgabewert 1 */
  174. }
  175.  
  176. /*****************************************************************************
  177. *
  178. *  Funktion       Speicher reservieren (reserve_mem)
  179. *  --------
  180. *
  181. *  Parameter    : laenge    :
  182. *                   Typ          : int
  183. *                   Wertebereich : 0 - MAX_INT
  184. *                   Bedeutung    : Laenge des zu reservierenden Speicher-
  185. *                                  bereiches in Bytes
  186. *
  187. *  Ergebnis     :
  188. *                   Typ          : char*
  189. *                   Wertebereich : Pointer auf Speicherbereich
  190. *                   Bedeutung    : Pointer auf reservierten Speicherbereich
  191. *
  192. *  Beschreibung : Es wird versucht, ueber malloc den angeforderten Speicher-
  193. *                 bereich zu allozieren. Falls dies fehlschlaegt, wird
  194. *                 eine Fehlermeldung ausgegeben, alle Files gesichert und
  195. *                 das Programm abgebrochen.
  196. *
  197. *****************************************************************************/
  198.  
  199. char *reserve_mem (laenge)
  200. int laenge;
  201. {
  202.   /* *** interne Daten *** */
  203.   register char *hilf; /* Rueckgabewert der Funktion */
  204.  
  205.   if (hilf = malloc (laenge)) /* Speicher anfordern */
  206.     return (hilf); /* klappte, Adresse zurueckgeben */
  207.   else             /* Sonst Fehlermeldung und Ende  */
  208.     no_mem_err();
  209. }
  210.  
  211. /*****************************************************************************
  212. *
  213. *  Funktion       Textzeile sichern (save_text)
  214. *  --------
  215. *
  216. *  Parameter    : txt       :
  217. *                   Typ          : char*
  218. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  219. *                   Bedeutung    : Zu sichernder String
  220. *
  221. *  Ergebnis     :
  222. *                   Typ          : char*
  223. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  224. *                   Bedeutung    : Pointer auf gesicherten String
  225. *
  226. *  Beschreibung : Fuer den uebergebenen String wird, falls der String
  227. *                 eine Laenge ungleich 0 hat und txt != NULL ist, Speicher
  228. *                 alloziert, der uebergebene String wird dorthin kopiert
  229. *                 und der Pointer auf den Bereich zurueckgegeben.
  230. *                 Ist die Stringlaenge 0 oder txt NULL, so wird ein
  231. *                 NULL-Pointer zurueckgegeben.
  232. *
  233. *****************************************************************************/
  234.  
  235. char *save_text(txt)
  236. register char *txt;
  237. {
  238.   /* *** interne Daten *** */
  239.   register int len; /* Laenge des abzuspeichernden Textes */
  240.  
  241.   if (!txt) /* Falls String leer, NULL-Pointer zurueckgeben */
  242.     return (NULL);
  243.   return ((len=strlen(txt))?strcpy(reserve_mem(len+1),txt):NULL);
  244. }
  245.  
  246. /*****************************************************************************
  247. *
  248. *  Funktion       Zeile freigeben (line_free)
  249. *  --------
  250. *
  251. *  Parameter    : txt       :
  252. *                   Typ          : char*
  253. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  254. *                   Bedeutung    : Freizugebende Zeile
  255. *
  256. *  Beschreibung : Falls der Pointer nicht gleich NULL ist, wird der Spei-
  257. *                 cherbereich, auf den er zeigt, freigegeben.
  258. *
  259. *****************************************************************************/
  260.  
  261. void line_free(txt)
  262. char *txt;
  263. {
  264.   if(txt)
  265.     free(txt);
  266. }
  267.  
  268. /*****************************************************************************
  269. *
  270. *  Funktion       String von hinten kopieren (revcpy)
  271. *  --------
  272. *
  273. *  Parameter    : s1         :
  274. *                   Typ          : char *
  275. *                   Wertebereich : Pointer auf Speicherbereich
  276. *                   Bedeutung    : Platz, an den zu kopierender String
  277. *                                  kopiert wird
  278. *                 s2         :
  279. *                   Typ          : char *
  280. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  281. *                   Bedeutung    : zu kopierender String
  282. *
  283. *  Ergebnis     :
  284. *                   Typ          : char *
  285. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  286. *                   Bedeutung    : s1
  287. *
  288. *  Beschreibung : s2 wird, von hinten beginnend, nach s1 kopiert.  Dies ist
  289. *                 zum Beispiel nuetzlich, wenn s2 und s1 gemeinsame Speicher-
  290. *                 bereiche haben und s2 nach s1 beginnt.
  291. *
  292. *****************************************************************************/
  293.  
  294. char *revcpy(s1,s2)
  295. register char *s1,*s2;
  296. {
  297.   /* *** interne Daten und Initialierung *** */
  298.   register char *s2e = s2 + strlen(s2); /* Zeiger auf Stringende */
  299.  
  300.   for(s1+=s2e-s2;s2e >= s2;*s1-- = *s2e--);
  301.   return(s1);
  302. }
  303.  
  304. /*****************************************************************************
  305. *
  306. *  Funktion       String vorwaerts kopieren (fwdcpy)
  307. *  --------
  308. *
  309. *  Parameter    : s1         :
  310. *                   Typ          : char *
  311. *                   Wertebereich : Pointer auf Speicherbereich
  312. *                   Bedeutung    : Platz, an den zu kopierender String
  313. *                                  kopiert wird
  314. *                 s2         :
  315. *                   Typ          : char *
  316. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  317. *                   Bedeutung    : zu kopierender String
  318. *
  319. *  Ergebnis     :
  320. *                   Typ          : char *
  321. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  322. *                   Bedeutung    : s1
  323. *
  324. *  Beschreibung : s2 wird, von vorne beginnend, nach s1 kopiert.
  325. *                 Diese Funktion wird bei ueberlappenden Strings benoetigt,
  326. *                 da strcpy keine Garantie fuer die Kopierrichtung gibt.
  327. *
  328. *****************************************************************************/
  329.  
  330. char *fwdcpy(s1,s2)
  331. register char *s1,*s2;
  332. {
  333.   if(!s2)                       /* wie strcpy */
  334.   {
  335.     if(s1)
  336.       *s1 = '\0';
  337.   }
  338.   else
  339.     while (*s1++ = *s2++);
  340.   return(s1);
  341. }
  342.  
  343. /*****************************************************************************
  344. *
  345. *  Funktion       Zwei Integer vertauschen (swap_int)
  346. *  --------
  347. *
  348. *  Parameter    : a         :
  349. *                   Typ          : int *
  350. *                   Wertebereich : Pointer auf Integer
  351. *                   Bedeutung    : zu vertauschender Integer
  352. *
  353. *               : b         :
  354. *                   Typ          : int *
  355. *                   Wertebereich : Pointer auf Integer
  356. *                   Bedeutung    : zu vertauschender Integer
  357. *
  358. *  Beschreibung : Die Integer, auf die die Pointer a und b zeigen, werden
  359. *                 mittels einer Hilfsvariable vertauscht.
  360. *
  361. ******************************************************************************/
  362.  
  363. void swap_int(a,b)
  364. int *a,*b;
  365. {
  366.   /* *** interne Daten *** */
  367.   int hilf; /* Hilfsvariable zum Vertauschen */
  368.  
  369.   hilf = *a;
  370.   *a = *b;
  371.   *b = hilf;
  372. }
  373.  
  374. /*****************************************************************************
  375. *
  376. *  Funktion       Lese JA/NEIN Abfrage (ja_nein)
  377. *  --------
  378. *
  379. *  Parameter    : s         :
  380. *                   Typ          : char *
  381. *                   Wertebereich : Pointer auf ASCII-Zeichenkette
  382. *                   Bedeutung    : Text der Abfrage
  383. *
  384. *  Ergebnis     :
  385. *                   Typ          : int
  386. *                   Wertebereich : TRUE,FALSE
  387. *                   Bedeutung    : Ergebnis der Abfrage: ja = TRUE
  388. *                                                        nein = FALSE
  389. *
  390. *  Beschreibung : s wird in der Statuszeile ausgegeben, danach ein Zeichen,
  391. *                 terminiert durch RETURN eingelesen. Ist das Zeichen nicht
  392. *                 in "JjNn" wird die Abfrage wiederholt.  Es wird FALSE
  393. *                 zurueckgegeben, falls das Zeichen 'n' oder 'N' war,
  394. *                 ansonsten ist der Returnwert TRUE.
  395. *
  396. *****************************************************************************/
  397.  
  398. int ja_nein (s)
  399. char *s;
  400. {
  401.   /* *** interne Daten *** */
  402.   short int jn; /* einzulesendes Zeichen */
  403.  
  404.   print_stat (s);           /* Uebergebenen String ausgeben   */
  405.   print_stat(PROMPT_YES_NO);  /* Zusatz anhaengen               */
  406. #ifdef MOUSE
  407.   mouse_jn_init(TRUE);      /* Maus für ja_nein aktivieren    */
  408. #endif
  409.   nodelay(status,TRUE); /* Fenster wg. Maus auf NODELAY schalten */
  410.   do                        /* Solange ein Zeichen lesen, bis */
  411.   { jn = newwgetch(status); /* es eins von j,J,y,Y,n,N ist        */
  412.     if (jn == -1)
  413.       DosSleep (10);
  414.   } while (!strchr ("jny,YJN",(char)jn)
  415. #ifdef MOUSE
  416.      && mouse_jn == NO_KLICK
  417. #endif
  418.                 );
  419.   nodelay(status,FALSE);  /* Wieder DELAY einschalten */
  420. #ifdef MOUSE
  421.   mouse_jn_init(FALSE);     /* Maus für ja_nein deaktivieren  */
  422. #endif
  423.   clear_stat();             /* Statuszeile wieder loeschen    */
  424.  
  425.   if (jn == 'n' || jn == 'N'
  426. #ifdef MOUSE
  427.  || mouse_jn == KLICK_RIGHT
  428. #endif
  429.                )
  430.     return (FALSE);
  431.   return (TRUE);
  432. }
  433.  
  434. #ifdef OWN_CURSES
  435. /******************************************************************************
  436. *
  437. * Funktion     : Zeilen- und Spaltenzahl ermitteln (set_lines_cols)
  438. * --------------
  439. *
  440. * Parameter    : modus       :
  441. *                  Typ          : char *
  442. *                  Wertebereich : Pointer auf ASCII-Zeichenkette
  443. *                  Bedeutung    : Aus der Umgebungsvariablen EHPINIT
  444. *                                 extrahierter Teil
  445. *
  446. * Beschreibung : Der aus der Umgebungsvariable stammende Teil hinter
  447. *                dem Bezeichner "screen" muß die Syntax <Spalten>x<Zeilen>
  448. *                haben. Das 'x' darf auch groa geschrieben sein.
  449. *                Ist der übergebene String syntaktisch korrekt so werden die
  450. *                Curses-Variablen LINES und COLS entsprechend gesetzt.
  451. *
  452. ******************************************************************************/
  453.  
  454. void set_lines_cols(modus)
  455. char *modus;
  456. {
  457.   char *zeil_str; /* Zeiger auf Tokenteil, der Zeilenzahl angibt */
  458.   int  lines,     /* Anzahl der Bildschirmzeilen */
  459.        cols;      /* Anzahl der Bildschirmspalten */
  460.  
  461.   if(!(zeil_str = strchr(modus,'x')) && !(zeil_str = strchr(modus,'X')))
  462.     return;  /* Falsches Format, Bildschirmgröße wird nicht verändert */
  463.   *zeil_str++ = '\0'; /* 'x' bzw. 'X' löschen, String in 2 Teile teilen */
  464.   cols = atoi(modus); /* Erste Zahl steht für die Spaltenangabe */
  465.   if(cols != 40 && cols != 80 && cols != 100 && cols != 132) /* Es werden nur die */
  466.     return;            /* Spaltenzahlen 40, 80, 100 und 132 unterstützt */
  467.   lines = atoi(zeil_str); /* Zweite Zahl des Strings steht für Zeilenangabe */
  468.   LINES = lines; /* Curses-Variablen LINES und COLS setzen */
  469.   COLS  = cols;
  470. }
  471. #endif
  472.  
  473. /*****************************************************************************
  474. *
  475. *  Funktion       Environment checken (check_env)
  476. *  --------
  477. *
  478. *  Beschreibung : Die Umgebung wird nach der Variablen EHPINIT abgesucht.
  479. *                 Wird sie gefunden, so wird der Inhalt analysiert.
  480. *                 Folgende Token haben folgenden Effekt:
  481. *                   deftab <n>   : Default-Tablaenge auf <n> setzen
  482. *                   nohelp       : Hilfstexte defaultmaessig ausgeschaltet
  483. *                   autoind      : Autoindentmodus defaultmaessig eingesch.
  484. *                   noshowblock  : Blockhervorhebung defaultmaessig eing.
  485. *                   conffile <f> : Name des Config-Files auf <f> setzen
  486. *                   loadfile <f> : Name des Load-Files auf <f> setzen
  487. *                   nobak        : Defaultmaessig keine .bak-Files
  488. *                   screen <mode>: Bildschirmgröße in Zeilen und Spalten
  489. *                   keys <f>     : Name des Tastaturbeschreibungsfiles = <f>
  490. *
  491. ****************************************************************************/
  492.  
  493. void check_env()
  494. {
  495.   /* *** interne Daten *** */
  496.   char *ehp_init, /* Zeiger auf Inhalt der Umgebungsvariable */
  497.        *token;    /* Zeiger auf aktuellen Parameter          */
  498.   int  i;         /* Integerwert der Tablaenge               */
  499.  
  500.   if(ehp_init = getenv("EHPINIT"))
  501.     while(token = strtok(ehp_init," "))
  502.     {
  503.       ehp_init = NULL;  /* fuer strtok */
  504.       if(!strcmp("deftab",token))
  505.       {
  506.     if(!(token = strtok(ehp_init," ")))
  507.       break;        /* war letzter token */
  508.     if((i = atoi(token)) > 0 && i < MAXLENGTH)
  509.     {
  510.       def_tab = i;
  511.       continue;
  512.     }
  513.       }
  514.       if(!strcmp("nohelp",token))
  515.     helpflag = FALSE;
  516.       else
  517.     if(!strcmp("autoind",token))
  518.       def_aiflag = TRUE;
  519.     else
  520.       if(!strcmp("noshowblock",token))
  521.         highblockflag = FALSE;
  522.       else
  523.         if(!strcmp("conffile",token))
  524.         {
  525.           if(!(token = strtok(ehp_init," ")))
  526.         break;        /* war letzter token */
  527.           conffile = token;
  528.         }
  529.         else
  530.           if(!strcmp("loadfile",token))
  531.           {
  532.         if(!(token = strtok(ehp_init," ")))
  533.           break;        /* war letzter token */
  534.         loadfile = token;
  535.           }
  536.           else
  537.         if(!strcmp("nobak",token))
  538.           backupflag = FALSE;
  539.  
  540. #ifdef OWN_CURSES /* Bildschirmgröße läßt sich nur mit dem eigenen Curses
  541.              anpassen ! */
  542.         else
  543.           if(!strcmp("screen",token))
  544.           {
  545.             if(!(token = strtok(ehp_init," ")))
  546.               break;        /* war letzter token */
  547.             set_lines_cols(token); /* Bildschirmgröße setzen */
  548.           }
  549. #endif
  550.           else
  551.             if(!strcmp("keys", token))
  552.             {
  553.               if(!(token = strtok(ehp_init," ")))
  554.             break;      /* war letzer Token */
  555.               tasten_inf = strcpy(reserve_mem (strlen(token)),token);
  556.             }
  557.     }
  558. }
  559.  
  560. /******************************************************************************
  561. *
  562. * Funktion     : Signal abfangen (catchsig)
  563. * --------------
  564. *
  565. * Beschreibung : Diese Funktion wird beim Auftreten des Break-Interruptes
  566. *                (Nummer 27) aufgerufen. Es wird das clear_buff-Flag gesetzt,
  567. *                wodurch beim nächsten Aufruf von newwgetch alle Puffer und
  568. *                Macros abgebrochen werden.
  569. *
  570. ******************************************************************************/
  571.  
  572. void catchsig(sig)
  573. int sig;
  574. {
  575.   /* Um ein waehrend der Abarbeitung dieser Routine auftretendes */
  576.   /* Signal abzufangen, wird das Signal auf SIG_IGN umgeleitet   */
  577.  
  578.   signal(sig,SIG_IGN);
  579. #ifdef OS2
  580.   if(sig == SIGINT || sig == SIGQUIT || sig == SIGBREAK)
  581. #else
  582.   if(sig == SIGINT || sig == SIGTERM)
  583. #endif
  584.     clear_buff = TRUE;  /* Macro- und Repeatpuffer loeschen */
  585.   else
  586.   {
  587.     if(ja_nein(PROMPT_FATAL))
  588.       save_all();
  589.     ende(sig, TRUE);     /* Speicherbereiche werden automat. v. Unix freigegeben */
  590.   }
  591.   signal(sig, catchsig); /* Adresse dieser Funktion wieder eintragen */
  592. }
  593.  
  594. /*****************************************************************************
  595. *
  596. *  Funktion       initialisieren (init)
  597. *  --------
  598. *
  599. *  Beschreibung : Die CURSES-Funktionen initscr(),noecho() und raw() werden
  600. *                 aufgerufen, um CURSES zu initialisieren, echo abzuschalten,
  601. *                 und die Abfrage von einzelnen Zeichen zu ermoeglichen.
  602. *                 Dann wird das Dummyelement der Windowliste initialisiert.
  603. *                 Es ist _w_i_c_h_t_i_g, daa check_env von initscr aufgerufen wird.
  604. *                 In check_env werden nämlich evtl. die Variablen LINES
  605. *                 und COLS angepaat, was vor der Bildschirminitalisierung
  606. *                 stattfinden mua. Ebenfalls in initscr können sich diese
  607. *                 beiden Werte nochmals ändern.
  608. *
  609. *****************************************************************************/
  610.  
  611. void init()
  612. {
  613.   /* *** interne Daten *** */
  614.   int i;    /* Fuer Eingabe der Terminaltypen */
  615.  
  616.   /* Pruefen, ob IO des Prozesses umgelenkt wurde */
  617.   if(!isatty(0) || !isatty(1) || !isatty(2))
  618.   {
  619.     fputs(PROMPT_IO_REDIR,stderr);
  620.     exit(1);
  621.   }
  622.  
  623. #ifdef OS2
  624.   set_os2_raw (TRUE);       /* !!! muß erste Aktion sein !!! */
  625. #endif
  626.   check_env();              /* Umgebungsvariable bearbeiten */
  627.   initscr();                /* Curses "einschalten" */
  628.   noecho();
  629.   raw(); /* Zeichen direkt, keine Signale verarbeiten */
  630.   nonl(); /* \r soll nicht in \n umgewandelt werden */
  631.   status = newwin(1,COLS,LINES-1,0); /* Statusfenster oeffnen */
  632.   lies_tasten();        /* Tastaturbelegung laden */
  633.   akt_winp = (win_typ*) reserve_mem (sizeof (win_typ)); /* Dummyfenster */
  634.   akt_winp->next = akt_winp->prev = akt_winp;           /* allozieren   */
  635.   akt_winp->filename = NULL; /* damit print_err testen kann, ob es */
  636.   akt_winp->winp = NULL;     /* schon ein Fenster gibt */
  637.  
  638.   /* Terminal stellt zu ersetzende Begriffe blinkend dar, */
  639.   /* Bloecke halbhell.                                    */
  640.   ersetzaddr = A_BLINK;
  641.   blockattr = A_BOLD;
  642.  
  643.   global_block.e_line = global_block.s_line = -1;
  644.   global_block.bstart = NULL;   /* PASTE-Puffer leer */
  645.   for(i=0;i<ANZ_MARKER;i++)     /* Marker loeschen   */
  646.     marker[i].window = marker[i].line = marker[i].col = -1;
  647.   for(i=0;i<ANZ_MACROS;i++)     /* Macros loeschen   */
  648.     macro[i].begin = macro[i].end = NULL;
  649. #ifdef MOUSE
  650.   init_mouse();
  651. #endif
  652.  
  653.   signal (SIGINT, catchsig); /* kommt wohl nicht durch, da CTRL-c im raw- */
  654. #ifdef OS2
  655.   signal (SIGBUS, catchsig); /* Modus nicht als Signal verarbeitet wird.  */
  656.   signal (SIGQUIT, catchsig);
  657.   signal (SIGBREAK, catchsig);
  658.   /* Jetzt muß der Semaphor erzeugt werden, der verhindert, daß sich von der
  659.      Maus und von der Tastatur empfangene Kommandos behindern. Dieser Sema-
  660.      phor wird als "owned" geöffnet, muß also erst "released" werden, damit
  661.      ein Kommando akzeptiert werden kann. */
  662.   DosCreateMutexSem (NULL, &sem_handle, DC_SEM_SHARED, TRUE);
  663. #else
  664.   signal (SIGABRT, catchsig);
  665.   signal (SIGTERM, catchsig);
  666.   signal (SIGSEGV, catchsig);
  667. #endif
  668. }
  669.  
  670. /*****************************************************************************
  671. *
  672. *  Funktion       editor beenden (ende)
  673. *  --------
  674. *
  675. *  Parameter    : r         :
  676. *                   Typ          : int
  677. *                   Wertebereich : -MAX_INT - +MAX_INT
  678. *                   Bedeutung    : Rueckgabewert des Programms
  679. *
  680. *                 wait_mouse: (Nur OS/2)
  681. *                   Typ          : char
  682. *                   Wertebereich : FALSE, TRUE
  683. *                   Bedeutung    : TRUE:  Warte auf die Beendigung des
  684. *                                         Mausthreads
  685. *                                  FALSE: Nicht auf Mausthread warten.
  686. *
  687. *  Beschreibung : Die Fenster werden mittels endwin() geschlossen und danach
  688. *                 exit aufgerufen.
  689. *
  690. *****************************************************************************/
  691.  
  692. void ende(r, 
  693. #ifdef OS2
  694.          wait_mouse)
  695. #endif
  696. int r;
  697. char wait_mouse;
  698. {
  699.   clear();      /* Bildschirm loeschen */
  700.   refresh();
  701.   endwin();     /* Curses beenden */
  702. #ifdef MOUSE
  703.   mouse_active = FALSE;  /* Maus nicht mehr benötigt */
  704. #ifdef OS2
  705.   /* Durch Setzen von mouse_active=FALSE beendet sich der Mouse-Thread
  706.      selbständig und die Maus wird geschlossen. Hier muß dann nur noch
  707.      auf die Terminierung des Threads gewartet werden. */
  708.   if (wait_mouse)
  709.   {
  710.     DosWaitThread (&mouse_ThreadID, DCWW_WAIT);
  711.     if (mouse_jn_ThreadID) /* Wurde schon einmal ja_nein aufgerufen? */
  712.       DosWaitThread (&mouse_jn_ThreadID, DCWW_WAIT);
  713.   }
  714. #else
  715.   set_mouse_int(0); /* Mausroutine maskieren */
  716. #endif
  717. #endif
  718. #ifndef OS2
  719.   *(long*)(27*4) = old_int; /* Vektor des Break-Interruptes restaurieren */
  720. #endif
  721.   exit(r);
  722. }
  723.  
  724.  
  725. /*****************************************************************************
  726. *
  727. *  Funktion       alle geaenderten Texte abspeichern (save_all)
  728. *  --------
  729. *
  730. *  Ergebnis     : TRUE: alle Dateien konnten abgespeichert werden.
  731. *                 FALSE: nicht alle Dateien ...
  732. *
  733. *  Beschreibung : Die zu den Fenstern gehoerigen Files werden abgespeichert,
  734. *                 sofern sie veraendert wurden.
  735. *
  736. *****************************************************************************/
  737.  
  738. int save_all()
  739. {
  740.   /* *** interne Daten und Initialisierung *** */
  741.   int     no_errflag = TRUE;   /* Zeigt Fehler beim Abspeichern an */
  742.   win_typ *d = akt_winp->next; /* Zeiger auf Dummy-Fenster         */
  743.  
  744.   check_buff();
  745.   akt_winp = d->next;
  746.   while (akt_winp != d)
  747.   {
  748.     if(akt_winp->changeflag && !schreib_file())
  749.       no_errflag = FALSE; /* schreib_file lieferte Fehler */
  750.     akt_winp = akt_winp->next;
  751.   }
  752.   akt_winp = d->prev; /* akt_winp restaurieren */
  753.   return(no_errflag);
  754. }
  755.  
  756. /*****************************************************************************
  757. *
  758. *  Funktion       Text und Fenster freigeben (alles_frei)
  759. *  --------
  760. *
  761. *  Beschreibung : Der fuer Texte und Fenster allozierte Speicherplatz wird
  762. *                 freigegeben.
  763. *
  764. *****************************************************************************/
  765.  
  766. void alles_frei()
  767. {
  768.   while(akt_winp != akt_winp->next)     /* noch ein Fenster da? */
  769.   {
  770.     free_text();  /* Text des Fensters freigeben */
  771.     delwin(akt_winp->winp); /* Fenster fuer Curses freigeben */
  772.     gb_win_frei(); /* gb_win_frei loescht Fenster aus Liste und */
  773.   }                /* macht akt_winp zu ->prev */
  774.   if(global_block.bstart)     /* globalen Block evtl. freigeben */
  775.     block_free(global_block.bstart);
  776.   line_free(sd_line);      /* zuletzt geloeschte Zeile freigeben */
  777.   free(akt_winp);          /* dummy auch freigeben */
  778. }
  779.  
  780. #ifndef OS2
  781. /*****************************************************************************
  782. *
  783. *  Funktion       Wildcards expandieren (do_wildcard_expansion)
  784. *  --------
  785. *
  786. *  Parameter    : argc         :
  787. *                   Typ          : int *
  788. *                   Wertebereich : Zeiger auf Integer
  789. *                   Bedeutung    : Zeiger auf bisherige Anzahl der Parameter
  790. *
  791. *                 argv         :
  792. *                   Typ          : char **[]
  793. *                   Wertebereich : Pointer auf Pointer auf Array von Pointer
  794. *                                  auf Parametern
  795. *                   Bedeutung    : 1. Parameter: Programmname
  796. *                                  restliche Parameter: zu expandierende
  797. *                                  Dateinamen
  798. *
  799. *  Beschreibung : Mittels der Funktionen findfirst und findnext werden
  800. *                 die als Parameter angegebenen Dateinamenmuster zu
  801. *                 vollständigen Dateinamen expandiert. argc aud argv
  802. *                 werden auf das entstehende Erbebnis gesetzt, das keine
  803. *                 Wildcards mehr enthält.
  804. *
  805. *****************************************************************************/
  806.  
  807. void do_wildcard_expansion(argc, argv)
  808. int *argc;
  809. char **argv[];
  810. {
  811.   int ende,               /* Kein weiteres File zum Pattern ?        */
  812.       complete_length,    /* Summe aller Stringlängen                */
  813.       new_argc,           /* Neue Parameteranzahl                    */
  814.       new_argv_index,     /* Index in neues Argumentarray            */
  815.       argv_index;         /* Index in argv, zählt die Dateiparameter */
  816.   struct ffblk file_info; /* Struktur für findfirst und findnext     */
  817.   struct filenamelist     /* Für die Konstruktion der neuen Liste    */
  818.   {
  819.     char                *name;
  820.     struct filenamelist *next;
  821.   } *p, *q, *first;       /* Laufzeiger und Listenstart              */
  822.   char **new_argv;        /* Neues Feld für Parameter                */
  823.  
  824.   if (*argc > 1) /* Nur etwas machen, wenn auch Parameter angegeben wurden */
  825.   {
  826.     /* Zunächst ein Dummy-Element für die Namenliste anlegen: */
  827.     first = p = (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  828.     p->next = NULL;
  829.     argv_index = 0;
  830.     new_argc = 1; /* Zumindest der Kommandoname */
  831.     complete_length = strlen ((*argv) [0]); /* Länge des Kommandos ! */
  832.     while (++argv_index < *argc)
  833.     {
  834.       ende = findfirst ((*argv) [argv_index], &file_info, 0);
  835.       if (ende)
  836.       { /* Überhaupt keinen passenden Namen, dann neue Datei! */
  837.     p->next =
  838.       (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  839.     p = p->next;
  840.     p->next = NULL;
  841.     p->name = strcpy ((char*) reserve_mem (strlen ((*argv) [argv_index])),
  842.               (*argv) [argv_index]);
  843.     complete_length += strlen ((*argv) [argv_index]) + 1;
  844.     new_argc++;
  845.       }
  846.       else
  847.     while (!ende)
  848.     {
  849.       p->next = 
  850.         (struct filenamelist *) reserve_mem (sizeof (struct filenamelist));
  851.       p = p->next;
  852.       p->next = NULL;
  853.       p->name = strcpy ((char*) reserve_mem(strlen (file_info.ff_name)+1),
  854.                 file_info.ff_name);
  855.       complete_length += strlen (file_info.ff_name) + 1;
  856.       new_argc++;
  857.       ende = findnext (&file_info);
  858.     }
  859.     }
  860.  
  861.     /* Jetzt die aufgebaute Liste in ein Array vom Typ char *[] verwandeln */
  862.     /* Achtung: Letzter Pointer muß NULL-Pointer sein! */
  863.     new_argv = (char **) reserve_mem ((new_argc+1) * sizeof (char*));
  864.     new_argv[0] = (*argv)[0];
  865.     new_argv_index = 1;
  866.     p = first->next;
  867.     while (p)
  868.     {
  869.       new_argv [new_argv_index++] = p->name;
  870.       p = p->next;
  871.     }
  872.     new_argv [new_argv_index] = NULL; /* Am Ende der Argumentliste muß ein NULL-Pointer stehen */
  873.     *argc = new_argc;
  874.     *argv = new_argv;
  875.     /* Jetzt temporäre Liste freigeben! */
  876.     p = first;
  877.     while (p)
  878.     {
  879.       q = p->next;
  880.       free (p);
  881.       p = q;
  882.     }
  883.   }
  884. }
  885. #endif
  886.  
  887.  
  888.  
  889. /*****************************************************************************
  890. *
  891. *  Funktion       parameter verarbeiten (hndl_params)
  892. *  --------
  893. *
  894. *  Parameter    : argc         :
  895. *                   Typ          : int
  896. *                   Wertebereich : 1 - ANZ_WIN
  897. *                   Bedeutung    : Anzahl der Parameter
  898. *
  899. *                 argv         :
  900. *                   Typ          : char **
  901. *                   Wertebereich : Pointer auf Array von Pointer auf
  902. *                                  Parametern
  903. *                   Bedeutung    : 1. Parameter: Programmname
  904. *                                  restliche Parameter: zu edierende Dateien
  905. *
  906. *                 anz_files    :
  907. *                   Typ          : int
  908. *                   Wertebereich : 0 - ANZ_WIN
  909. *                   Bedeutung    : Anzahl der schon eingelesenen Dateien
  910. *
  911. *  Beschreibung : Die Kommandozeilenparameter werden als Filenamen interpre-
  912. *                 tiert und in den Editor geladen.
  913. *                 Konnten keine Files geladen werden, so wird das Programm
  914. *                 abgebrochen.
  915. *
  916. *****************************************************************************/
  917.  
  918. void hndl_params(argc,argv,anz_files)
  919. int argc,anz_files;
  920. char **argv;
  921. {
  922. #ifdef OS2                  /* OS/2 stellt _wildcard zur Verfügung, */
  923.   _wildcard (&argc, &argv); /* um Patterns zu expandieren */
  924. #else
  925.   do_wildcard_expansion (&argc, &argv);
  926. #endif
  927.   if(argc>1)   /* Wurden Parameter angegeben ? */
  928.   {
  929.     while(--argc) /* Fuer jeden Parameter ein Fenster oeffnen */
  930.     {
  931.       if (koppel_win())
  932.       {
  933.     akt_winp->filename = save_text(argv[argc]);
  934.     if(!lies_file()) /* und versuchen, die Datei zu laden */
  935.     {
  936.       free(akt_winp->dummyp);
  937.       gb_win_frei(); /* klappt das nicht, Fenster wieder schliessen */
  938.     }
  939.     else
  940.     {
  941.       anz_files++;   /* Sonst Anzahl der geladenen Files erhoehen */
  942.       open_window(); /* und Fenster initialisieren */
  943.     }
  944.       }
  945.       else /* Konnte Fenster nicht geoeffnet werden, Fehlermeldung */
  946.       {
  947.     print_err(W_COUNT_ERRTEXT);
  948.     break;
  949.       }
  950.     }
  951.     if(!anz_files) /* Wenn keines der angegebenen Files geladen werden  */
  952.     {              /* konnte, Fehlermeldung ausgeben und Editor beenden */
  953.       print_stat(PROMPT_NO_FILE);
  954.       wart_ret();
  955.       ende(0, TRUE);
  956.     }
  957.     setz_cursor(W_AKT);  /* falls letzte Datei nicht geladen werden konnte, */
  958.   }                 /* wird kein setz_cursor gemacht */
  959.   else              /* Wurden keine Parameter angegeben und konnte    */
  960.     if(!anz_files && !laden()) /* kein File geladen werden, versuchen */
  961.       ende(0, TRUE);   /* Dateinamen vom User zu holen. Falls Fehler, Ende */
  962. }
  963.  
  964.  
  965. /*****************************************************************************
  966. *
  967. *  Funktion       main (main)
  968. *  --------
  969. *
  970. *  Parameter    : argc         :
  971. *                   Typ          : int
  972. *                   Wertebereich : 1 - ANZ_WIN
  973. *                   Bedeutung    : Anzahl der Parameter
  974. *
  975. *  Parameter    : argv         :
  976. *                   Typ          : char **
  977. *                   Wertebereich : Pointer auf Array von Pointer auf
  978. *                                  Parametern
  979. *                   Bedeutung    : 1. Parameter: Programmname
  980. *                                  restliche Parameter: zu edierende Dateien
  981. *
  982. *  Beschreibung : main() startet den Editor und enthaelt die Hauptschleife, die
  983. *                 einen Befehl holt und diesen ausfuehrt, bis das Programm
  984. *                 beendet werden soll.
  985. *
  986. *****************************************************************************/
  987.  
  988. int main (argc,argv)
  989. int argc;
  990. char **argv;
  991. {
  992.   init();  /* Tastaturbelegung laden, Variablen initialisieren, Umgebungs- */
  993.        /* variable bearbeiten, Signale abfangen, Curses initialisieren */
  994.   hndl_params(argc,argv,read_config(argc)); /* Config-Datei lesen und Para-*/
  995.                         /* meter auswerten             */
  996.   while (1)
  997.     auswertung (aktcode = taste(akt_winp->winp)); /* Tastenkombination lesen */
  998. }                                                 /* und auswerten           */
  999.